package com.oa.erp.ass.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.mdp.core.service.BaseService;
import com.mdp.core.utils.BaseUtils;
import com.oa.erp.ass.dto.CategoryTreeDto;
import com.oa.erp.ass.entity.AssetCategory;
import com.oa.erp.ass.mapper.AssetCategoryMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月8日
 */
@Service
public class AssetCategoryService extends BaseService<AssetCategoryMapper, AssetCategory> {
    static Logger logger = LoggerFactory.getLogger(AssetCategoryService.class);

    /**
     * 自定义查询，支持多表关联
     *
     * @param page 分页条件
     * @param ew   一定要，并且必须加@Param("ew")注解
     * @param ext  如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
     * @return
     */
    public List<Map<String, Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String, Object> ext) {
        return baseMapper.selectListMapByWhere(page, ew, ext);
    }

    /**
     * 请在此类添加自定义函数
     */

    public final static String ROOT = "0";

    /**
     * 获取资产分类树形结构
     *
     * @param branchId
     * @return
     */
    public List<CategoryTreeDto> listAssetCategoryByTree(IPage page, QueryWrapper qw, String branchId) {
        AssetCategory assetCategory = new CategoryTreeDto();
        assetCategory.setBranchId(branchId);
        // todo List<AssetCategory> assetCategoryList = this.selectListByWhere(assetCategory); 会抛出异常，不知道为啥
        List<AssetCategory> assetCategoryList = this.selectListMapByWhere(page, qw, BaseUtils.toMap(assetCategory))
                .stream().map((value) -> BaseUtils.fromMap(value, AssetCategory.class)).collect(Collectors.toList());
        //转换Tree
        List<CategoryTreeDto> categoryTreeDtos = Lists.newArrayList();
        for (AssetCategory category : assetCategoryList) {
            CategoryTreeDto categoryTreeDto = CategoryTreeDto.adapt(category);
            categoryTreeDtos.add(categoryTreeDto);
        }
        return categoryListToTree(categoryTreeDtos);
    }

    private List<CategoryTreeDto> categoryListToTree(List<CategoryTreeDto> categoryTreeDtos) {
        if (CollectionUtils.isEmpty(categoryTreeDtos)) {
            return Lists.newArrayList();
        }
        Multimap<String, CategoryTreeDto> categoryTreeDtoMultimap = ArrayListMultimap.create();
        List<CategoryTreeDto> rootList = Lists.newArrayList();
        for (CategoryTreeDto dto : categoryTreeDtos) {
            categoryTreeDtoMultimap.put(dto.getLevel(), dto);
            if (ROOT.equals(dto.getLevel())) {
                rootList.add(dto);
            }
        }
        //在此可以进行排序

        //递归生成tree
        transformCategoryTree(rootList, ROOT, categoryTreeDtoMultimap);
        return rootList;
    }

    private void transformCategoryTree(List<CategoryTreeDto> rootList, String level, Multimap<String, CategoryTreeDto> categoryTreeMap) {
        for (int i = 0; i < rootList.size(); i++) {
            //1.遍历每个元素
            CategoryTreeDto categoryTreeDto = rootList.get(i);
            //2.处理数据，计算下一层数据
            String nextLevel = calculateLevel(level, categoryTreeDto.getCategoryId());
            //3. 处理下一层
            List<CategoryTreeDto> tempList = (List<CategoryTreeDto>) categoryTreeMap.get(nextLevel);
            if (!CollectionUtils.isEmpty(tempList)) {
                // 设置下一层部门
                categoryTreeDto.setChildren(tempList);
                // 递归，进入到下一层处理
                transformCategoryTree(tempList, nextLevel, categoryTreeMap);
            }
        }
    }

    public static String calculateLevel(String parentLevel, String parentId) {
        if (StringUtils.isEmpty(parentLevel)) {
            return ROOT;
        } else {
            String[] s = new String[]{parentLevel, parentId};
            return String.join(".", s);
        }
    }

    /**
     * 添加一条资产分类
     *
     * @param assetCategory
     */
    public void insertAssetCategory(AssetCategory assetCategory) {
        assetCategory.setLevel(calculateLevel(getLevel(assetCategory.getBranchId(), assetCategory.getParentId()), assetCategory.getParentId()));
        this.insert(assetCategory);
    }

    private String getLevel(String branchId, String id) {
        AssetCategory assetCategory = new AssetCategory();
        assetCategory.setCategoryId(id);

        assetCategory.setBranchId(branchId);
        AssetCategory result = this.selectOneObject(assetCategory);
        if (result == null) {
            return null;
        }
        return result.getLevel();
    }

    public List<AssetCategory> selectIsExitOtherCategory(Map<String, Object> param) {
        return baseMapper.selectIsExitOtherCategory(param);
    }
}

